#include <libpq-fe.h>
#include <iostream>
#include <string>
#include "pgsql.h"
#include <chrono>
#include <fstream>
#include <vector>
#include "table.h"
#include "predicate.h"
#include "tuplesense.h"

using namespace std;

//database-config
const char* hostaddr = "localhost";
const char* port = "5432";
const char* dbname = "tpch0001";
const char* user = "postgres";
const char* password = "";


time_t GetCurrentTimeMsec() {
	auto time = chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now());
	time_t timestamp = time.time_since_epoch().count();
	return timestamp;
}


void Stringsplit(const string& str, const char split, vector<string>& res)
{
	if (str == "")		return;
	string strs = str + split;
	size_t pos = strs.find(split);

	while (pos != strs.npos)
	{
		string temp = strs.substr(0, pos);
		res.push_back(temp);
		strs = strs.substr(pos + 1, strs.size());
		pos = strs.find(split);
	}
}

PGconn* conn;

int main(int argc,char* argv[]) {
	
	time_t t_begin = GetCurrentTimeMsec();

	PGsql pgsql(hostaddr, port, dbname, user, password);
	
	conn = pgsql.getConn();

	string sql1 = "select l_partkey,l_orderkey,l_suppkey,l_quantity from lineitem where l_returnflag = 'N' order by l_partkey";
	vector<string> col_names1 = { "l_partkey","l_orderkey","l_suppkey","l_quantity"};
	Table t1;
	t1.input_data(conn,"lineitem", sql1,col_names1);
	//t1.add_tracebit();
	t1.table_print(10);

	string sql2 = "select p_partkey from part order by p_partkey";
	vector<string> col_names2 = { "p_partkey" };
	Table t2;
	t2.input_data(conn, "part", sql2, col_names2);
	t2.add_tracebit();
	t2.table_print(10);

	Table t4;
	t4.table_foreignkey_join(t1, "l_partkey", t2, "p_partkey", t4);
	//t4.table_print(10);
	t4.orderby_Col("l_orderkey");
	t4.table_print(10);

	string sql3 = "select o_orderkey from orders order by o_orderkey";
	vector<string> col_names3 = { "o_orderkey" };
	Table t3;
	t3.input_data(conn, "orders", sql3, col_names3);
	t3.add_tracebit();
	t3.table_print(10);


	Table t5;
	t5.table_foreignkey_join(t4, "l_orderkey", t3, "o_orderkey", t5);
	t5.table_print(10);

	TupleSense ts;
	ts.all_tables.push_back(t2);
	ts.all_tables.push_back(t3);
	ts.all_tables.push_back(t5);
	ts.sense_tables.push_back("part");
	ts.sense_tables.push_back("orders");
	ts.computeTupleSenseGroup(t5, "l_suppkey", "l_quantity", t1);
	//ts.computeTupleSense(t5, "l_quantity", t1);

	time_t t_end = GetCurrentTimeMsec();

	cout << "[Timecost] timecost : " << (t_end - t_begin) << endl;

	
}

